﻿using DotNetSpeech;
using Newtonsoft.Json.Linq;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WeighClient.Model;
using WeighClient.Utils;

namespace WeighClient.Windows
{
    /// <summary>
    /// NodeRed.xaml 的交互逻辑
    /// </summary>
    public partial class NodeRedBak : Window
    {
        SynchronizationContext _syncContext = null;
        delegate void MyDelegate(Object value);
        SpVoice speech = null;
        private IModel channel = null;

        public NodeRedBak()
        {
            InitializeComponent();
            _syncContext = SynchronizationContext.Current;
            this.Loaded += Window_Loaded;

            speech = new SpVoice();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            HttpServer server = App.GetHttpServer();
            if (null != server)
            {
                HttpServer.sendMsgEvent += Client_sendMsgEvent;
            }
            //连接消息队列
            var factory = new ConnectionFactory();
            factory.HostName = App.GetConfig().Mq_HostName;
            factory.UserName = App.GetConfig().Mq_UserName;
            factory.Password = App.GetConfig().Mq_Password;
            var connection = factory.CreateConnection();
            channel = connection.CreateModel();

            subscriptionMQ();
        }

        //订阅集控端消息
        private void subscriptionMQ()
        {
            var consumer = new EventingBasicConsumer(channel);//消费者

            channel.BasicConsume("Queue_" + App.GetConfig().DeviceCode + "_Server", true, consumer);//消费消息
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body.ToArray());

                JObject jsonObj = JObject.Parse(message);
                string from = (string)jsonObj.GetValue("from");
                if ("monitor".Equals(from))
                {
                    Server_sendMsgEvent(jsonObj);
                }
            };
        }
        private void Client_sendMsgEvent(Object obj)
        {
            MyDelegate d = new MyDelegate(DealClientMessage);
            this.Dispatcher.Invoke(d, obj);
        }
        private void Server_sendMsgEvent(Object obj)
        {
            MyDelegate d = new MyDelegate(DealServerMessage);
            this.Dispatcher.Invoke(d, obj);
        }
        void DealClientMessage(Object obj)
        {
            JObject jsonObj = JObject.Parse(obj.ToString());
            String type = (String)jsonObj.GetValue("type");
            
            if ("Weigh".Equals(type))
            {
                //获取重量
                JObject detailObj = (JObject)jsonObj.GetValue("detail");
                String weigh = (String)detailObj.GetValue("weigh");
                String isSteady = (String)detailObj.GetValue("isSteady");
                
                _syncContext.Post(SetWeigh, weigh);
                _syncContext.Post(SetSteady, isSteady);

                //向集控端发送实时重量
                if ("1".Equals(isSteady))
                {
                    isSteady = "稳定";
                }
                else
                {
                    isSteady = "不稳定";
                }
                JObject jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "Weight");
                jsonParamObj.Add("weight", weigh);
                jsonParamObj.Add("steady", isSteady);

                _syncContext.Post(SendMqMessage, jsonParamObj);
            }
            else if ("GetCarNo".Equals(type))
            {
                //获取车号
                JObject detailObj = (JObject)jsonObj.GetValue("detail");
                String carNumber = (String)detailObj.GetValue("carNumber");
                _syncContext.Post(SetCarNo, carNumber);
                //向集控端发送车牌号
                JObject jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "GetCarNo");
                jsonParamObj.Add("carNo", carNumber);

                _syncContext.Post(SendMqMessage, jsonParamObj);

                //向集控端发送信息
                jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "VoiceAndLed");
                jsonParamObj.Add("voiceMsg", App.GetConfig().DeviceName + "," + carNumber + ",上磅");

                _syncContext.Post(SendMqMessage, jsonParamObj);
            }
            else if ("PostVoiceMessage".Equals(type))
            {
                String message = (String)jsonObj.GetValue("message");
                _syncContext.Post(AddVoiceLogTxt, message);

                //向集控端发送信息
                JObject jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "VoiceAndLed");
                jsonParamObj.Add("voiceMsg", App.GetConfig().DeviceName +","+ message);

                _syncContext.Post(SendMqMessage, jsonParamObj);
            }
            else if ("PostMessage".Equals(type))
            {
                String message = (String)jsonObj.GetValue("message");
                _syncContext.Post(AddLogTxt, message);
            }
            else if ("PostError".Equals(type))
            {
                String message = (String)jsonObj.GetValue("message");
                String devalue = (String)jsonObj.GetValue("devalue");

                _syncContext.Post(AddLogTxt, message);

                //向集控端发送信息
                JObject jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "Error");
                jsonParamObj.Add("message", App.GetConfig().DeviceName + "," + message);
                jsonParamObj.Add("devalue", "99");

                _syncContext.Post(SendMqMessage, jsonParamObj);
            }
            else if ("LoadBillInfo".Equals(type))
            {
                JObject detailJSON = (JObject)jsonObj.GetValue("detail");
                //_syncContext.Post(AddLogTxt, detailObj.ToString());

                String id = (String)detailJSON.GetValue("id");
                String orderCode = (String)detailJSON.GetValue("billNo");
                String carNo = (String)detailJSON.GetValue("carNumber");
                String productName = (String)detailJSON.GetValue("productName");
                String corpName = (String)detailJSON.GetValue("corpName");
                String position = (String)detailJSON.GetValue("position");
                String planNum = (String)detailJSON.GetValue("planNum");
                String _guid = (String)detailJSON.GetValue("guid");
                Bill bill = new Bill();

                bill.id = id;
                bill.orderCode = orderCode;
                bill.carNo = carNo;
                bill.productName = productName;
                bill.corpName = corpName;
                bill.position = position;
                bill.planNum = planNum;
                bill.videoCarNo = App.GetRunTimeVariable().CarNo;

                bill.weightStatus = (String)detailJSON.GetValue("weightStatus");
                bill.yuanfaNum = (String)detailJSON.GetValue("yuanfaNum");
                bill.chazhi = (String)detailJSON.GetValue("chazhi");
                bill.fayou = (String)detailJSON.GetValue("fayou");
                bill.pizhong = (String)detailJSON.GetValue("pizhong");
                bill.maozhong = (String)detailJSON.GetValue("maozhong");
                bill.jingzhong = (String)detailJSON.GetValue("jingzhong");
                bill.qianbiao = (String)detailJSON.GetValue("qianbiao");
                bill.houbiao = (String)detailJSON.GetValue("houbiao");
                bill.busitype = (String)detailJSON.GetValue("busitype");
                bill.operatorName = "";

                bill.guid = _guid;

                //向集控端发送提单信息
                JObject jsonParamObj = new JObject();
                jsonParamObj.Add("from", "client");
                jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonParamObj.Add("type", "BillInfo");
                jsonParamObj.Add("billObj", JObject.FromObject(bill));

                _syncContext.Post(SendMqMessage, jsonParamObj);

                _syncContext.Post(SetBillInfo, bill);
            }
            else if ("Print".Equals(type))
            {
                _syncContext.Post(print, null);
            }
            else if ("GetLoginUserInfo".Equals(type))
            {
                GetLoginUserInfo();
            }
            else if ("Complete".Equals(type))
            {
                _syncContext.Post(SetCarNo, "");
                _syncContext.Post(SetBillInfo, new Bill());
                //_syncContext.Post(AddLogMessage, new LogInfo("等待计量"));

                JObject jsonPramObj = new JObject();
                jsonPramObj.Add("from", "client");
                jsonPramObj.Add("clientId", App.GetConfig().DeviceCode);
                jsonPramObj.Add("type", "ClearBillInfo");
                jsonPramObj.Add("message", "计量完成");

                _syncContext.Post(SendMqMessage, jsonPramObj);
            }

        }
        void GetLoginUserInfo()
        {
            //获取监控端操作员身份信息
            JObject jsonParamObj = new JObject();
            jsonParamObj.Add("from", "client");
            jsonParamObj.Add("clientId", App.GetConfig().DeviceCode);
            jsonParamObj.Add("type", "GetLoginUserInfo");
            SendMqMessage(jsonParamObj);
        }
        void DealServerMessage(Object obj)
        {
            JObject jsonObj = JObject.Parse(obj.ToString());
            String type = (String)jsonObj.GetValue("type");
            if ("AutoWeigh".Equals(type))
            {
                String autoWeigh = (String)jsonObj.GetValue("value");
                if ("true".Equals(autoWeigh))
                {
                    App.GetConfig().AutoWeigh = true;
                }
                else
                {
                    App.GetConfig().AutoWeigh = false;
                }
                JObject reqObj = new JObject();
                reqObj.Add("type", "AutoWeigh");
                reqObj.Add("value", autoWeigh);
                SendNodeRedMessage("PostMessage/AutoWeighChange", reqObj);
            }
            else if ("ReadCard".Equals(type))
            {
                JObject reqObj = new JObject();
                SendNodeRedMessage("PostMessage/ReadCard", reqObj);
            }
            else if ("SaveWeight".Equals(type))
            {
                JObject reqObj = new JObject();
                SendNodeRedMessage("PostMessage/SaveWeigh", reqObj);
            }
            else if ("DealError".Equals(type))
            {
                JObject reqObj = new JObject();
                SendNodeRedMessage("PostMessage/DealError", reqObj);
            }
            else if ("ServerOperatorInfo".Equals(type))
            {
                JObject reqObj = new JObject();
                JObject operatorObj = new JObject();
                String id = (String)jsonObj.GetValue("loginUserId");
                String name = (String)jsonObj.GetValue("loginUserName");
                operatorObj.Add("id", id);
                operatorObj.Add("name", name);
                reqObj.Add("operator", operatorObj);
                SendNodeRedMessage("PostMessage/ServerOperatorInfo", reqObj);
            }
            else if ("UploadClientAutoWeigh".Equals(type))
            {
                JObject reqObj = new JObject();
                SendNodeRedMessage("PostMessage/UploadClientAutoWeigh", reqObj);
            }
            else if ("ChangeDoorStatus".Equals(type))
            {
                JObject reqObj = new JObject();
                String inOut = (String)jsonObj.GetValue("inOut");
                String status = (String)jsonObj.GetValue("status");
                reqObj.Add("inOut", inOut);
                reqObj.Add("status", status);
                SendNodeRedMessage("PostMessage/ChangeDoorStatus", reqObj);
            }
        }
        private void SetCarNo(object text)
        {
            //this.txtCarNo.Text = text.ToString();
            this.txtLog.Text += "获取车号：" + text.ToString() + "\n";
        }
        private void SetWeigh(object text)
        {
            this.txtWeight.Text = text.ToString();
        }
        private void SetSteady(object val)
        {
            if ("1".Equals(val))
            {
                txtSteady.Text = "稳定";
                txtSteady.Foreground = Brushes.Green;
            }
            else
            {
                txtSteady.Text = "不稳定";
                txtSteady.Foreground = Brushes.Red;
            }
        }
        private void AddLogTxt(object text)
        {
            this.txtLog.Text += text.ToString() + "\n";
        }
        private void SetBillInfo(Object obj)
        {
            /*
            Bill billObj = (Bill)obj;
            this.txtBillCode.Text = billObj.orderCode;
            this.txtProductName.Text = billObj.productName;
            this.txtPiZhong.Text = billObj.pizhong;
            this.txtMaoZhong.Text = billObj.maozhong;
            this.txtJingZhong.Text = billObj.jingzhong;

            this.txtCorpName.Text = billObj.corpName;
            this.txtPosition.Text = billObj.position;

            this.txtPlanNum.Text = billObj.planNum;
            this.txtCarNo.Text = billObj.carNo;
            this.txtVideoCarNo.Text = billObj.videoCarNo;

            JObject jsonObj = JObject.FromObject(billObj);*/
        }
        private void AddVoiceLogTxt(object text)
        {
            this.txtLog.Text += text.ToString() + "\n";
            speak(text.ToString());
        }
        private void speak(String message)
        {
            try
            {
                speech.Speak(string.Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
                if (null != message)
                {
                    speech.Speak(message, SpeechVoiceSpeakFlags.SVSFlagsAsync);
                }
            }
            catch (Exception ex) { }
        }
        private void print(object obj)
        {
            Bill bill = new Bill();
            //PrintUtils.printWeighOrder(bill);
        }
        private void Button_Click_XiaoPiao(object sender, RoutedEventArgs e)
        {
            //PrintUtils.printWeighOrder(new Bill());
        }

        private void Button_Click_ReadCard(object sender, RoutedEventArgs e)
        {
            /*
            JObject requestJSON = new JObject();
            requestJSON.Add("type", "ReadCard");
            String result = HttpPostHelper.doHttpPost("http://127.0.0.1:1880/PostMessage", requestJSON.ToString());
            */
            byte[] ReceiveBytes = new byte[17];
            ReceiveBytes[0] = 0x2;
            ReceiveBytes[1] = 0x31;
            ReceiveBytes[2] = 0x30;
            ReceiveBytes[3] = 0x20;
            ReceiveBytes[4] = 0x20;
            ReceiveBytes[5] = 0x20;
            ReceiveBytes[6] = 0x20;
            ReceiveBytes[7] = 0x20;
            ReceiveBytes[8] = 0x30;
            ReceiveBytes[9] = 0x30;
            ReceiveBytes[10] = 0x20;
            ReceiveBytes[11] = 0x20;
            ReceiveBytes[12] = 0x20;
            ReceiveBytes[13] = 0x20;
            ReceiveBytes[14] = 0x30;
            ReceiveBytes[15] = 0x30;
            ReceiveBytes[16] = 0xd;

            String hexString = ByteUtils.byteToHexStr(ReceiveBytes);
            AddLogTxt(hexString);

            string valStr = hexString.Substring(10, 8);
            AddLogTxt(valStr);
            valStr = valStr.Substring(1, 1) + valStr.Substring(3, 1) + "." + valStr.Substring(5, 1) + valStr.Substring(7, 1);

            AddLogTxt(valStr);
        }

        private void SendNodeRedMessage(String path,JObject reqObj)
        {
            String result = HttpPostHelper.doHttpPost(App.GetConfig().NodeRedUrl + path, reqObj.ToString());
        }
        private void SendMqMessage(Object obj)
        {
            JObject jsonObj = (JObject)obj;

            if (null != channel)
            {
                var properties = channel.CreateBasicProperties();
                properties.DeliveryMode = 1;

                string message = jsonObj.ToString();

                channel.BasicPublish("", "Queue_" + App.GetConfig().DeviceCode + "_Client", properties, Encoding.UTF8.GetBytes(message));
            }
        }
        private void Button_Click_VoiceTest(object sender, RoutedEventArgs e)
        {
            speak("获取车牌：鲁 E 0 2 0 0");
        }
    }
}
